package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qingcheng.dao.OrderItemMapper;
import com.qingcheng.dao.OrderLogMapper;
import com.qingcheng.dao.OrderMapper;
import com.qingcheng.entity.PageResult;
import com.qingcheng.pojo.goods.StockBack;
import com.qingcheng.pojo.order.Order;
import com.qingcheng.pojo.order.OrderConfig;
import com.qingcheng.pojo.order.OrderItem;
import com.qingcheng.pojo.order.OrderLog;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.goods.StockBackService;
import com.qingcheng.service.order.*;
import com.qingcheng.util.IdWorker;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 返回全部记录
     *
     * @return
     */
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

    /**
     * 分页查询
     *
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    public PageResult<Order> findPage(int page, int size) {
        PageHelper.startPage(page, size);
        Page<Order> orders = (Page<Order>) orderMapper.selectAll();
        return new PageResult<Order>(orders.getTotal(), orders.getResult());
    }

    /**
     * 条件查询
     *
     * @param searchMap 查询条件
     * @return
     */
    public List<Order> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return orderMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     *
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    public PageResult<Order> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page, size);
        Example example = createExample(searchMap);
        Page<Order> orders = (Page<Order>) orderMapper.selectByExample(example);
        return new PageResult<Order>(orders.getTotal(), orders.getResult());
    }

    /**
     * 根据Id查询
     *
     * @param id
     * @return
     */
    public Order findById(String id) {
        return orderMapper.selectByPrimaryKey(id);
    }

    @Autowired
    private CartService cartService;

    @Reference
    private SkuService skuService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private PreferentialService preferentialService;

    /**
     * 新增
     *
     * @param order
     */
    @Transactional
    public Map<String, Object> add(Order order) {

        //1.获取选中的购物车
        List<Map<String, Object>> cartList = cartService.findNewOrderItemList(order.getUsername());
        List<OrderItem> orderItemList = cartList.stream().filter(cart -> (boolean) cart.get("checked"))
                .map(cart -> (OrderItem) cart.get("item"))
                .collect(Collectors.toList());

        //2.扣减库存
        if (!skuService.deductionStock(orderItemList)) {
            throw new RuntimeException("库存不足！");
        }
        try {

            //3.保存订单主表
            order.setId(idWorker.nextId() + "");

            IntStream numStream = orderItemList.stream().mapToInt(OrderItem::getNum);
            IntStream moneytStream = orderItemList.stream().mapToInt(OrderItem::getMoney);
            int totalNum = numStream.sum();
            int totalMoney = moneytStream.sum();
            int preMoney = cartService.preferential(order.getUsername());  //满减优惠金额
            order.setTotalNum(totalNum);//总数量
            order.setTotalMoney(totalMoney); //总金额
            order.setPreMoney(preMoney);//优惠金额
            order.setPayMoney(totalMoney - preMoney);//支付金额
            order.setCreateTime(new Date());//订单创建时间
            order.setOrderStatus("0");//订单状态
            order.setPayStatus("0");//支付状态
            order.setConsignStatus("0");//发货状态

            orderMapper.insert(order);
            //发送 订单延迟支付信息
            sendPayDelayMessage(order.getId());


            //4.保存订单明细表
            //打折比例
            //打折比例  ???----》公共比例和订单详情价格比例不能混为一谈，看是什么样的平台，这样写有问题
            //根据 category 分类获得 不同的折扣 cartService 中的 preferential 方法
            // 根据username 获取最高优惠，遍历获得的Map<Integer, IntSummaryStatistics>
            //如果categoryId == orderItem.getCategoryId3() -->orderItem.setPayMoney(原本价格-优惠金额)

            //按分类聚合统计每个分类的金额    group by
            Map<Integer, IntSummaryStatistics> cartMap = orderItemList.stream()
                    .collect(Collectors.groupingBy(OrderItem::getCategoryId3, Collectors.summarizingInt(OrderItem::getMoney)));
            //循环结果，统计每个分类的优惠金额，计算每个类品的总金额
            double proportion = 0.0;
            for (Integer categoryId : cartMap.keySet()) {
                // 获取品类的消费金额
                int money = (int) cartMap.get(categoryId).getSum(); //一个类目总金额
//                int count = (int) cartMap.get(categoryId).getCount();//一个类目中的商品数量
                int singlePreMoney = preferentialService.findPreMoneyByCategoryId(categoryId, money); //获取优惠金额
                for (OrderItem orderItem : orderItemList) {

                    if (orderItem.getCategoryId3().equals(categoryId)) {
                        orderItem.setId(idWorker.nextId() + "");
                        orderItem.setOrderId(order.getId());
                        proportion = (double) (money - singlePreMoney) / money;
                        orderItem.setPayMoney((int) (orderItem.getMoney() * proportion));
                        orderItemMapper.insert(orderItem);
                    }
                }
                System.out.println("分类：" + categoryId + "  消费金额：" + money + " 优惠金额：" + preMoney);

            }


           /* String username = order.getUsername();

            List<Integer> list = cartService.singlePreferential(username);
            for(OrderItem orderItem:orderItemList ){
                orderItem.setId(idWorker.nextId()+"" );
                orderItem.setOrderId( order.getId() );
                //计算单个商品的优惠价格
                Integer categoryId3 = orderItem.getCategoryId3();

                *//*int singlePreMoney = cartService.singlePre(username, categoryId3,orderItem.getMoney());//单个商品的优惠价
                orderItem.setPayMoney(orderItem.getMoney()-singlePreMoney);*//*
                int singlePreMoney = 0 ;
                for (Integer categoryId : list) {
                    if(categoryId3.equals(categoryId)){
                        singlePreMoney = preferentialService.findPreMoneyByCategoryId(categoryId, orderItem.getMoney());
                    }
                }
                orderItem.setPayMoney(orderItem.getMoney()-singlePreMoney);
                orderItemMapper.insert(orderItem);
            }*/

            //int x=1/0;
        } catch (Exception e) {
            e.printStackTrace();
            //发送回滚消息
            rabbitTemplate.convertAndSend("", "queue.skuback", JSON.toJSONString(orderItemList));
            throw new RuntimeException("创建订单失败");
        }

        //5.清除购物车
        cartService.deleteCheckedCart(order.getUsername());

        Map map = new HashMap();
        map.put("ordersn", order.getId());
        map.put("money", order.getPayMoney());
        return map;

    }

    /**
     * 修改
     *
     * @param order
     */
    public void update(Order order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 删除
     *
     * @param id
     */
    public void delete(String id) {
        orderMapper.deleteByPrimaryKey(id);
    }


    @Autowired
    private OrderLogMapper orderLogMapper;

    @Override
    @Transactional
    public void updatePayStatus(String orderId, String transactionId) {
        System.out.println("调用修改订单状态");
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if (order != null && "0".equals(order.getPayStatus())) {
            //修改订单状态等信息
            order.setPayStatus("1");//支付状态
            order.setOrderStatus("1");//订单状态
            order.setUpdateTime(new Date());//修改日期
            order.setPayTime(new Date());//支付日期
            order.setTransactionId(transactionId);//交易流水号
            orderMapper.updateByPrimaryKeySelective(order);//修改

            //记录订单日志
            OrderLog orderLog = new OrderLog();
            orderLog.setId(idWorker.nextId() + "");
            orderLog.setOperater("system");//系统
            orderLog.setOperateTime(new Date());//操作时间
            orderLog.setOrderStatus("1");//订单状态
            orderLog.setPayStatus("1");//支付状态
            orderLog.setRemarks("支付流水号：" + transactionId);//备注
            orderLog.setOrderId(orderId);
            orderLogMapper.insert(orderLog);

        }
    }

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private WxPayService wxPayService;

    @Reference
    private StockBackService stockBackService;

    /**
     * 处理超时支付的订单
     *
     * @param orderId
     */
    @Override
    public void overtimeOrder(String orderId) {

        try {
            Order order = findById(orderId);
            if (order != null) {
                String orderStatus = order.getOrderStatus();
                if ("0".equals(orderStatus)) {
                    //订单状态为0 ,调用微信查询订单 api
                    Map map = wxPayService.queryPayStatus(orderId);
                    // System.out.println("===微信订单号===:"+map.get("transaction_id"));
                    if ("SUCCESS".equals(map.get("result_code")) && map.get("transaction_id") != null) {
                        //已经支付 改变支付状态
                        order.setPayStatus("1");
                        order.setOrderStatus("1");
                        order.setTransactionId(map.get("transaction_id").toString());
                        orderMapper.updateByPrimaryKeySelective(order);
                    } else {
                        //关闭订单api最短时间 5分钟后才可以调用
//                        if (new Date().getTime() - order.getCreateTime().getTime() > 5 * 60 * 1000) {
                            //关闭微信支付 api
                            map.put("out_trade_no", orderId);
                            Map<String, String> closeMap = wxPayService.closePayOrder(map);
                            if ("SUCCESS".equals(closeMap.get("result_code"))) {
                                //微信订单关闭成功
                                //数据回滚
                                List<OrderItem> orderItemList = orderItemService.findByOrderId(orderId);
                                stockBackService.addList(orderItemList);
                                //记录日志
                            }
//                        }

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("异常");
            //记录日志
        }

    }

    /**
     * 根据orderId 查询
     *
     * @param orderId
     * @return
     */
    @Override
    public Order findByOrderId(String orderId) {
        return orderMapper.findByOrderId(orderId);
    }

    /**
     * 合并订单
     *
     * @param orderId1
     * @param orderId2
     */
    @Override
    public boolean merge(String orderId1, String orderId2) {
        Order order1 = findById(orderId1);
        Order order2 = findById(orderId2);
        List<OrderItem> orderItem1 = orderItemService.findByOrderId(orderId1);//订单详情
        List<OrderItem> orderItem2 = orderItemService.findByOrderId(orderId2);//订单详情
        //判断用户名 和地址 是否相等
        if (order1 != null && order2 != null) {
            if (order1.getUsername().equals(order2.getUsername()) && order1.getReceiverAddress().equals(order2.getReceiverAddress())) {
                //更新订单主表
                order1.setTotalNum(order1.getTotalNum() + order2.getTotalNum());//总数量
                order1.setTotalMoney(order1.getTotalMoney()+order2.getTotalMoney());//总金额
                order1.setPayMoney(order1.getPayMoney() + order2.getPayMoney());//实付金额
                order1.setPreMoney(order1.getPreMoney() + order2.getPreMoney());//优惠价格
                order1.setUpdateTime(new Date());//更新时间

                //更新订单详情
                //合并订单详情 遍历
                for (OrderItem item1 : orderItem1) {
                    for (OrderItem item2 : orderItem2) {
                        //如果skuid 一样，代表商品一样，可以合并相同的商品
                        if(item1.getSkuId().equals(item2.getSkuId())){
                            //合并相同的商品
                            item1.setNum(item1.getNum() + item2.getNum());//合并数量
                            item1.setMoney(item1.getMoney() + item2.getMoney());//合并金额
                            item1.setPayMoney(item1.getPayMoney() + item2.getPayMoney());//合并实付金额
                            //更新数据
                            orderItemMapper.updateByPrimaryKeySelective(item1);
                            //删除item2
                            orderItemMapper.deleteByPrimaryKey(item2);
                            break;
                        }
                        //如果不相同，则插入
                        orderItemMapper.insertSelective(item2);
                        orderItemMapper.deleteByPrimaryKey(item2);
                    }
                }

                //更新主订单
                orderMapper.updateByPrimaryKeySelective(order1);
                //从订单 逻辑删除
                order2.setUpdateTime(new Date());
                order2.setIsDelete("1");
                orderMapper.updateByPrimaryKeySelective(order2);
                return true;
            }
            return false;
        }else{
            return false;
        }

    }

    /**
     * 拆分订单
     * @param orderItems 要拆分的订单详情
     */
    @Override
    public void splitOrderItem(List<OrderItem> orderItems) {

    }

    @Autowired
    private OrderConfigService orderConfigService;

    /***
     * 支付 延时消息发送
     * @param orderId
     */
    public void sendPayDelayMessage(String orderId) {
        rabbitTemplate.convertAndSend(
                "exchange.delay.order.begin",
                "delay",
                orderId,       //发送数据
                new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        //消息有效期:时间由 后台传过来，要与后台衔接  查询数据库 获得延迟时间 OrderConfig
                        OrderConfig orderConfig = orderConfigService.findById(1);
                        Integer orderTimeout = orderConfig.getOrderTimeout() * 60 * 1000;
                        //测试时用10秒
                        message.getMessageProperties().setExpiration(String.valueOf(orderTimeout));
                        return message;
                    }
                });
    }

    /**
     * 构建查询条件
     *
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap) {
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if (searchMap != null) {
            // 订单id
            if (searchMap.get("id") != null && !"".equals(searchMap.get("id"))) {
                criteria.andLike("id", "%" + searchMap.get("id") + "%");
            }
            // 支付类型，1、在线支付、0 货到付款
            if (searchMap.get("payType") != null && !"".equals(searchMap.get("payType"))) {
                criteria.andLike("payType", "%" + searchMap.get("payType") + "%");
            }
            // 物流名称
            if (searchMap.get("shippingName") != null && !"".equals(searchMap.get("shippingName"))) {
                criteria.andLike("shippingName", "%" + searchMap.get("shippingName") + "%");
            }
            // 物流单号
            if (searchMap.get("shippingCode") != null && !"".equals(searchMap.get("shippingCode"))) {
                criteria.andLike("shippingCode", "%" + searchMap.get("shippingCode") + "%");
            }
            // 用户名称
            if (searchMap.get("username") != null && !"".equals(searchMap.get("username"))) {
                criteria.andLike("username", "%" + searchMap.get("username") + "%");
            }
            // 买家留言
            if (searchMap.get("buyerMessage") != null && !"".equals(searchMap.get("buyerMessage"))) {
                criteria.andLike("buyerMessage", "%" + searchMap.get("buyerMessage") + "%");
            }
            // 是否评价
            if (searchMap.get("buyerRate") != null && !"".equals(searchMap.get("buyerRate"))) {
                criteria.andLike("buyerRate", "%" + searchMap.get("buyerRate") + "%");
            }
            // 收货人
            if (searchMap.get("receiverContact") != null && !"".equals(searchMap.get("receiverContact"))) {
                criteria.andLike("receiverContact", "%" + searchMap.get("receiverContact") + "%");
            }
            // 收货人手机
            if (searchMap.get("receiverMobile") != null && !"".equals(searchMap.get("receiverMobile"))) {
                criteria.andLike("receiverMobile", "%" + searchMap.get("receiverMobile") + "%");
            }
            // 收货人地址
            if (searchMap.get("receiverAddress") != null && !"".equals(searchMap.get("receiverAddress"))) {
                criteria.andLike("receiverAddress", "%" + searchMap.get("receiverAddress") + "%");
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if (searchMap.get("sourceType") != null && !"".equals(searchMap.get("sourceType"))) {
                criteria.andLike("sourceType", "%" + searchMap.get("sourceType") + "%");
            }
            // 交易流水号
            if (searchMap.get("transactionId") != null && !"".equals(searchMap.get("transactionId"))) {
                criteria.andLike("transactionId", "%" + searchMap.get("transactionId") + "%");
            }
            // 订单状态
            if (searchMap.get("orderStatus") != null && !"".equals(searchMap.get("orderStatus"))) {
                criteria.andLike("orderStatus", "%" + searchMap.get("orderStatus") + "%");
            }
            // 支付状态
            if (searchMap.get("payStatus") != null && !"".equals(searchMap.get("payStatus"))) {
                criteria.andLike("payStatus", "%" + searchMap.get("payStatus") + "%");
            }
            // 发货状态
            if (searchMap.get("consignStatus") != null && !"".equals(searchMap.get("consignStatus"))) {
                criteria.andLike("consignStatus", "%" + searchMap.get("consignStatus") + "%");
            }
            // 是否删除
            if (searchMap.get("isDelete") != null && !"".equals(searchMap.get("isDelete"))) {
                criteria.andLike("isDelete", "%" + searchMap.get("isDelete") + "%");
            }

            // 数量合计
            if (searchMap.get("totalNum") != null) {
                criteria.andEqualTo("totalNum", searchMap.get("totalNum"));
            }
            // 金额合计
            if (searchMap.get("totalMoney") != null) {
                criteria.andEqualTo("totalMoney", searchMap.get("totalMoney"));
            }
            // 优惠金额
            if (searchMap.get("preMoney") != null) {
                criteria.andEqualTo("preMoney", searchMap.get("preMoney"));
            }
            // 邮费
            if (searchMap.get("postFee") != null) {
                criteria.andEqualTo("postFee", searchMap.get("postFee"));
            }
            // 实付金额
            if (searchMap.get("payMoney") != null) {
                criteria.andEqualTo("payMoney", searchMap.get("payMoney"));
            }

        }
        return example;
    }

}
